package com.zhang.filter;

import com.zhang.constants.ApiConstant;
import com.zhang.constants.WebConstant;
import com.zhang.dataSource.ApiDBservice;
import com.zhang.dataSource.IDBServcice;
import com.zhang.exception.ApiException;
import com.zhang.principal.ApiInfo;
import com.zhang.principal.UserInfo;
import org.apache.catalina.connector.ResponseFacade;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ApiFilter extends AccessControlFilter {

    private IDBServcice dbServcice;


    private ApiDBservice apiDBservice;

    public ApiFilter(IDBServcice dbServcice, ApiDBservice apiDBservice) {
        this.dbServcice = dbServcice;
        this.apiDBservice = apiDBservice;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        String path = WebUtils.getPathWithinApplication(WebUtils.toHttp(request));

        ApiInfo apiInfo = apiDBservice.findWithPathEquals(path);

        try {
            if (apiInfo == null) throw new ApiException("请求接口不存在");
            if (apiInfo.getStatus().equals(ApiConstant.API_STATUS_FORBIDEN)) throw new ApiException("请求接口已失效");
            //允许匿名访问的接口
            if (apiInfo.isAnonymous()) return true;

            //获取当前请求用户
            Subject subject = SecurityUtils.getSubject();
            if (subject != null && subject.isAuthenticated() && subject.getPrincipal() instanceof UserInfo){
                return dbServcice.isPermitted((UserInfo) subject.getPrincipal(), apiInfo.getPermissionCode());
            }

            throw new ApiException("无权访问此接口");
        }catch (ApiException e){
            request.setAttribute(WebConstant.EXCEPTION_MESSAGE,e.getMessage());
            request.setAttribute(WebConstant.EXCEPTION_TYPE,WebConstant.API_EXCEPTION);
        }

        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        request.getRequestDispatcher("/api/error/shiroFilter").forward(request,response);

        //返回false表示已处理  不需要走接下来的拦截器了
        return false;

    }
}
